package com.dhcc.DRGsHosp.facade.impl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.inject.Named;

import org.openkoala.koala.commons.InvokeResult;
import org.openkoala.security.shiro.CurrentUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.context.ContextLoader;

import com.dhcc.DRGsHosp.application.CostSubApplication;
import com.dhcc.DRGsHosp.application.DrgsIndexCalApplication;
import com.dhcc.DRGsHosp.application.MrAppendPageApplication;
import com.dhcc.DRGsHosp.application.MrBaseInfoApplication;
import com.dhcc.DRGsHosp.application.MrDiagnoseApplication;
import com.dhcc.DRGsHosp.application.MrExpenseApplication;
import com.dhcc.DRGsHosp.application.MrIpInfoApplication;
import com.dhcc.DRGsHosp.application.MrOperationApplication;
import com.dhcc.DRGsHosp.application.MrqDictDetailApplication;
import com.dhcc.DRGsHosp.application.MrqDictWeightApplication;
import com.dhcc.DRGsHosp.application.MrqScoreApplication;
import com.dhcc.DRGsHosp.application.MrqScoreDetailApplication;
import com.dhcc.DRGsHosp.application.MrqViolationApplication;
import com.dhcc.DRGsHosp.core.domain.CostSub;
import com.dhcc.DRGsHosp.core.domain.IndexCal;
import com.dhcc.DRGsHosp.core.domain.MedicalRecordQuality;
import com.dhcc.DRGsHosp.core.domain.MrAppendPage;
import com.dhcc.DRGsHosp.core.domain.MrBaseInfo;
import com.dhcc.DRGsHosp.core.domain.MrDiagnose;
import com.dhcc.DRGsHosp.core.domain.MrExpense;
import com.dhcc.DRGsHosp.core.domain.MrIpInfo;
import com.dhcc.DRGsHosp.core.domain.MrOperation;
import com.dhcc.DRGsHosp.core.domain.MrqDictRules;
import com.dhcc.DRGsHosp.core.domain.MrqScore;
import com.dhcc.DRGsHosp.core.domain.MrqScoreDetail;
import com.dhcc.DRGsHosp.core.domain.MrqViolation;
import com.dhcc.DRGsHosp.facade.MedicalRecordQualityFacade;
import com.dhcc.DRGsHosp.facade.MrqDictDetailFacade;
import com.dhcc.DRGsHosp.facade.MrqDictRulesFacade;
import com.dhcc.DRGsHosp.facade.MrqScoreFacade;
import com.dhcc.DRGsHosp.infra.util.DrgsIndex;
import com.dhcc.DRGsHosp.infra.util.GlobalData;
import com.dhcc.DRGsHosp.infra.util.MonitorResultUtil;
import com.dhcc.DRGsHosp.infra.util.StringUtils;
import com.dhcc.DRGsHosp.infra.util.qualitycontrol.QualityControlMedicalRecord;

/**
 *
 * @Description: 首页业务类
 * @param:
 * @return:
 * @auther: chenhanlin
 * @date: 2018/8/2 11:10
 */
@Named("MedicalRecordQualityFacadeImplliuhongjun20181014")
public class MedicalRecordQualityFacadeImpl implements MedicalRecordQualityFacade {
    private static final Logger logger = LoggerFactory.getLogger(MedicalRecordQualityFacadeImpl.class);
    @Autowired
    private MrqDictRulesFacade mrqDictRulesFacade;
    @Autowired
    private MrqScoreFacade mrqScoreFacade;
    @Autowired
    private DrgsIndexCalApplication drgsIndexCalApplication ;
    @Autowired
    private MrBaseInfoApplication mrBaseInfoApplication ;
    @Autowired
    private MrIpInfoApplication mrIpInfoApplication ;
    @Autowired
    private MrOperationApplication mrOperationApplication ;
    @Autowired
    private MrDiagnoseApplication mrDiagnoseApplication ;
    @Autowired
    private MrExpenseApplication mrExpenseApplication ;
    @Autowired
    private MrqDictWeightApplication mrqDictWeightApplication ;
    @Autowired
    private MrqScoreDetailApplication mrqScoreDetailApplication ;
    @Autowired
    private MrqViolationApplication mrqViolationApplication ;
    @Autowired
    private CostSubApplication costSubApplication ;
    @Autowired
    private MrqScoreApplication mrqScoreApplication ;
    @Autowired
    private MrqDictDetailApplication mrqDictDetailApplication ;
    @Autowired
    private MrAppendPageApplication mrAppendPageApplication;
	@Autowired
	private MrqDictDetailFacade mrqDictDetailFacade;//记录操作日志用

    // 当前运行状态
    private Map<String,String> statusMap = new HashMap<>() ;
    // 质控相关数据是否已准备好
    private boolean isPrepared = false ;
    // 质控规则
    private List<MrqDictRules> rulesList = null ;
    // 规则完整性Map key:ruleCode value:completeFlag
    private Map<String,String> ruleCompleteMap = new HashMap<>() ;
    // 质控规则对应的质控项
    private Map<String,Double>  ruleDetail = null ;
    // 费用子项列表
    private Map<String,String> costSubMap = new HashMap<>() ;
    // 质控方法对象
    private QualityControlMedicalRecord qualityControl = new QualityControlMedicalRecord() ;
    // 医师类型
    private List<String> docTypeList = new ArrayList<>(Arrays.asList("clinic","protomedicus","physician","resident"));
	// 分类得分统计未整理的数据
	private List<Map<String, Object>> scoreMap = new ArrayList<Map<String, Object>>() ;
	// 分类得分统计--大类满分明细
	private Map<String,Double> totalScoreMap = new HashMap<>() ;	
	// 分类得分统计--分类满分明细
	private Map<String,Double> partScoreMap = new HashMap<>() ;	
	// 分类得分统计--分类保底得分明细
	private Map<String,Double> minScoreMap = new HashMap<>() ;
	//医院名称
	private String hospName ;

    /**
     * @param condition
     * @return
     * @throws
     * @Description: 首页违规病例明细
     * @author chenhanlin
     * @date 2018/8/11 21:00
     */
    @Cacheable(value = "drgsCaseDetail3.1.0", key = "'MedicalRecordQualityFacadeImpl'+'loadMRQualityCaseDtl'+"
            + "#p0['pardepgroupCode'] + #p0['deps'] + #p0['pardepCode'] + #p0['parwardCode']  + "
            + "#p0['pargroupCode'] + #p0['protomedicus'] + #p0['resident'] + #p0['physician'] + "
            + "#p0['dateFrom'] + #p0['dateTo'] + #p0['hospCode'] + "
            + "#p0['pageNo'] + #p0['pageSize'] + #p0['searchCondtion'] + #p0['orderColumn'] + #p0['orderMethod'] + "
            + "#p0['ruleCode'] + #p0['outDate']+ #p0['monitorType']+ #p0['groupCode']+ #p0['ward'] ")
    @Override
    public Map<String,Object> loadMRQualityCaseDtl(Map<String, Object> condition) {
        Map<String,Object> resultMap = new HashMap<String, Object>();
        if(condition.get("dateFrom")!=null && condition.get("dateTo") !=null){
            condition.put("dateFrom",DrgsIndex.formateDateFrom(condition.get("dateFrom")+"")) ;
            condition.put("dateTo",DrgsIndex.formateDateTo(condition.get("dateTo")+"")) ;
        }
        List<String> slist = mrqScoreApplication.getScoreCode();
        String hospName = mrqDictWeightApplication.getHospName();
        if(null != slist && slist.size()>0){
        	//调整了sql 的顺序，以前的sql执行太慢了
        	String monitorType = MonitorResultUtil.object2String(condition.get("monitorType")) ;
            StringBuffer sqlb = new StringBuffer() ;
            sqlb.append(" SELECT violation.PMAININDEX \"pmainIndex\" \n" ) ;
            sqlb.append("   ,a.P00050000 P00050000,a.P00060000 P00060000 , P00070000 \"gender\" \n" ) ;
            sqlb.append("    ,to_char(ipinfo.P00250000,'yyyy-mm-dd') \"inDate\" ,to_char(ipinfo.P00290000,'yyyy-mm-dd') \"outDate\" \n" ) ;
            sqlb.append("   ,dep.DEP_NAME DEP_NAME \n" ) ;
            sqlb.append("   ,ipinfo.P00800000 \"totalFee\" \n" ) ;
            sqlb.append("   ,score.TOTAL_SCORE \"totalScore\",score.RATING_LEVEL \"ratingLevel\" \n" ) ;
            for(String str : slist ){
            	sqlb.append("  ,s."+str ) ;
            }
            sqlb.append("    ,violation.ruleDetail \"ruleDetail\",violation.cnt \"cnt\" \n" ) ;
            sqlb.append(" FROM  ( \n" ) ;
            sqlb.append("       SELECT distinct violation.PMAININDEX, replace(wm_concat(rule.RULE_INTRODUCTION),',','|') ruleDetail ,count(1) cnt \n" ) ;
            sqlb.append("       from drgs.MRQ_VIOLATION violation \n" ) ;
            sqlb.append("       LEFT JOIN DRGS.MR_BASEINFO a on a.PMAININDEX = violation.PMAININDEX \n" ) ;
            if(condition.get("hospCode") != null){
            	sqlb.append("   and instr(:hospCode,a.p00010001)>0 \n ") ;
            }
            sqlb.append("       LEFT JOIN drgs.MR_IPINFO ipinfo on ipinfo.PMAININDEX = violation.PMAININDEX \n" ) ;
            if(condition.get("dateFrom")!=null && condition.get("dateTo") !=null && condition.get("dateType") !=null ){
                String dateField = "" ;
                // 时间字段
                if("outDate".equals(condition.get("dateType"))){ // 出院日期
                    dateField = "ipinfo.P00290000" ;
                } else if("pushDate".equals(condition.get("dateType"))) { // 推送日期
                    dateField = "a.push_date" ;
                }
                sqlb.append("   and to_char("+dateField+",'yyyy-mm-dd')  BETWEEN :dateFrom AND :dateTo \n ") ;
            }
            sqlb.append("       LEFT JOIN  drgs.MRQ_DICT_RULES rule on rule.RULE_CODE = violation.RULE_CODE \n" ) ;
            sqlb.append("       and rule.SCORE_CODE in (  \n" ) ;
            sqlb.append("       	select distinct t.score_code from drgs.MRQ_DICT_SCORE t where instr('"+hospName+"',t.hosp_name)>0 \n" ) ;
            sqlb.append("       ) \n" ) ;
            if (condition.get("groupCode") != null) {
                sqlb.append(" -replace_t_doctor- \n ") ;
            }
            sqlb.append("       WHERE violation.PMAININDEX IS NOT NULL \n" ) ;
            sqlb.append(" and 1=1 and 2=2 \n ") ;
            sqlb.append("       group by violation.PMAININDEX \n" ) ;
            sqlb.append("   ) violation \n" ) ;
            //
            sqlb.append(" 	LEFT JOIN ( \n" ) ;
            sqlb.append(" 		select * from ( \n" ) ;
            sqlb.append(" 			select t.pmainindex,t.score_code,sum(t.score) score from drgs.MRQ_SCORE_TOTAL t group by t.pmainindex,t.score_code \n" ) ;
            sqlb.append(" 		) pivot (sum(score) for score_code in ( " ) ;
            for(int i =0;i<slist.size();i++){
            	if(i<slist.size()-1){
            		sqlb.append("'"+slist.get(i)+"' "+slist.get(i)+", " ) ;
            	}else{
            		sqlb.append("'"+slist.get(i)+"' "+slist.get(i)+" " ) ;
            	}
            }
            sqlb.append("  		)) \n" ) ;
            sqlb.append(" 	) s on s.pmainindex = violation.pmainindex \n" ) ;

            sqlb.append("   LEFT JOIN drgs.MR_BASEINFO a on violation.PMAININDEX = a.PMAININDEX \n" ) ;
            sqlb.append("   LEFT JOIN drgs.MR_IPINFO ipinfo on violation.PMAININDEX = ipinfo.PMAININDEX \n" ) ;
            sqlb.append(" 	LEFT JOIN drgs.T_DEPARTMENT dep on dep.DEP_CODE = ipinfo.P00300001 \n" ) ;
            sqlb.append(" 	LEFT JOIN drgs.T_WARD ward ON ward.WARD_CODE = ipinfo.P00310001 \n" ) ;
            sqlb.append(" 	LEFT JOIN drgs.MRQ_SCORE_BASEINFO score on violation.PMAININDEX = score.PMAININDEX \n") ;
            sqlb.append(" WHERE 4=4  \n \n ") ;
            String sql = sqlb.toString() ;
            // 条件替换
            sql = repalceSqlByConditon(sql,condition) ;
            /**
             * 搜索条件
             */
            CharSequence searchCondtion = MonitorResultUtil.object2String(condition.get("searchCondtion")) ;
            if (StringUtils.hasLength(searchCondtion)) {
                String  mrSearch =  " (INSTR( a.P00050000,'" + searchCondtion + "') > 0 OR "// 病案号搜索
                        + " INSTR( dep.DEP_NAME ,'" + searchCondtion + "') > 0 OR "
                        + " INSTR( a.P00060000,'" + searchCondtion + "') > 0 ) ";//姓名搜索
                sql = sql.replace("1=1" ," 1=1 and "+mrSearch+" \n ") ;

            }

            String caseCountHead = "SELECT COUNT(1) caseCount FROM ( ";
            String caseCountFoot = " ) ";
            Integer caseCnt = drgsIndexCalApplication.executeQueryForInt(caseCountHead+sql+caseCountFoot,condition) ;
            // 分页sql
            String pageSqlHead = "SELECT * FROM (SELECT PAGERESULT.*, ROWNUM RN FROM (";
            // 排序的字段和方法(desc,asc)
            String orderColumn = MonitorResultUtil.object2String(condition.get("orderColumn"));
            String orderMethod = MonitorResultUtil.object2String(condition.get("orderMethod"));
            String pageSqlFoot = " ORDER BY " + orderColumn + " " + orderMethod + ") PAGERESULT ) WHERE rn>"+condition.get("rowStart")+" and rn <=("+condition.get("rowStart")+"+"+condition.get("pageSize")+" )";

            List<Map<String,Object>> resultListF = null;
            try {
                resultListF = drgsIndexCalApplication.excuteQueryForList(pageSqlHead+sql+pageSqlFoot,condition) ;
            } catch (Exception e) {
                resultListF = new ArrayList<>() ;
                e.printStackTrace();
            }

            // 添加序号
            for (Map<String,Object> map : resultListF) {
                String[] ruleDetaila = MonitorResultUtil.object2String(map.get("ruleDetail")).split("\\|") ;
                StringBuffer ruleDetailb = new StringBuffer() ;
                if(ruleDetaila.length>1){
                    for (int i=0; i<ruleDetaila.length ; i++) {
                        ruleDetailb.append("("+(i+1)+")"+ruleDetaila[i]+" @@ ") ;
                    }
                    map.put("ruleDetail",ruleDetailb) ;
                }
                switch (MonitorResultUtil.object2String(map.get("ratingLevel"))) {
                    case "1" : map.put("ratingLevelDsc","优") ; break;
                    case "2" : map.put("ratingLevelDsc","良") ; break;
                    case "3" : map.put("ratingLevelDsc","中") ; break;
                    case "4" : map.put("ratingLevelDsc","差") ; break;
                    default : map.put("ratingLevelDsc","未知") ;
                }
            }
            resultMap.put("iTotalRecords", caseCnt);
            resultMap.put("iTotalDisplayRecords", caseCnt);
            resultMap.put("aaData", resultListF);                 	
        }
        return resultMap ;  
    }
    
    /**
     *
     * @param condition
     * @return
     * @throws
     * @Description: 质控概况
     * @author chenhanlin
     * @date 2018/8/6 15:13
     */
    @Override
    public List<Map<String, Object>> overviewMRCount(Map<String, Object> condition) {
        if(condition.get("dateFrom")!=null && condition.get("dateTo") !=null){
            condition.put("dateFrom",DrgsIndex.formateDateFrom(condition.get("dateFrom")+"")) ;
            condition.put("dateTo",DrgsIndex.formateDateTo(condition.get("dateTo")+"")) ;
        }
        StringBuffer sqlb = new StringBuffer() ;
        sqlb.append(" SELECT \n" ) ;
        sqlb.append(" -- 总病案数 \n" ) ;
        sqlb.append(" count(score.PMAININDEX) \"totalMedicalRecord\" \n" ) ;
        sqlb.append(" -- 首页质量平均得分 \n" ) ;
        sqlb.append(" ,round(avg(score.TOTAL_SCORE),2) \"avgScore\" \n" ) ;
        sqlb.append(" -- 完整个数 \n" ) ;
        sqlb.append(" ,sum(CASE WHEN score.COMPLETE_FLAG = 1 THEN 1 ELSE 0 END ) \"completeCount\" \n" ) ;
        sqlb.append(" -- 合格个数 \n" ) ;
        sqlb.append(" ,sum(CASE WHEN score.RATING_LEVEL<4 THEN 1 ELSE 0 END ) \"qualifiedCount\" \n" ) ;
        sqlb.append(" -- 优秀个数 \n" ) ;
        sqlb.append(" ,sum(CASE WHEN score.RATING_LEVEL = 1 THEN 1 ELSE 0 END ) \"goodCount\" \n" ) ;
        sqlb.append(" FROM  drgs.MRQ_SCORE_BASEINFO score \n" ) ;
        sqlb.append(" LEFT JOIN drgs.MR_BASEINFO a on score.PMAININDEX = a.PMAININDEX \n" ) ;
        sqlb.append(" LEFT JOIN drgs.MR_IPINFO ipinfo on a.PMAININDEX = ipinfo.PMAININDEX  \n" ) ;
        joinSqlByCondtion(sqlb,condition) ;
        sqlb.append(" WHERE 1=1 \n" ) ;
        String sql = sqlb.toString() ;
        // 条件替换
        sql = repalceSqlByConditon(sql,condition) ;
        List<Map<String,Object>> resultListF = drgsIndexCalApplication.excuteQueryForList(sql,condition) ;
        return resultListF == null ? new ArrayList<Map<String, Object>>() : resultListF ;
    }

    @Override
    public List<Map<String, Object>> overviewItemCount(Map<String, Object> condition) {
        if(condition.get("dateFrom")!=null && condition.get("dateTo") !=null){
            condition.put("dateFrom",DrgsIndex.formateDateFrom(condition.get("dateFrom")+"")) ;
            condition.put("dateTo",DrgsIndex.formateDateTo(condition.get("dateTo")+"")) ;
        }
        String hospName = mrqDictWeightApplication.getHospName();
        StringBuffer sqlb = new StringBuffer() ;
        sqlb.append(" SELECT \n" ) ;
        sqlb.append(" -- 病例数 \n" ) ;
        sqlb.append(" count(score.PMAININDEX) \"caseCnt\" \n" ) ;
        sqlb.append(" -- 项数 \n" ) ;
        sqlb.append(" ,sum(dictA.rcA) \"itemsCnt\" \n" ) ;
        sqlb.append(" -- 违反的必填项 \n" ) ;
        sqlb.append(" ,sum(violation.requiredCount) \"violateRequiredCount\" \n" ) ;
        sqlb.append(" -- 所有必填项 \n" ) ;
        sqlb.append("  ,sum(dict.rc) \"requiredCount\" \n" ) ;
        sqlb.append(" -- A 违规项 \n" ) ;
        sqlb.append("  ,sum(detail.requiredCount) \"violateACount\" \n" ) ;
        sqlb.append(" -- A 病例数 \n" ) ;
        sqlb.append("  ,count(detail.PMAININDEX) \"violateACaseCount\" \n" ) ;
        sqlb.append(" FROM  drgs.MRQ_SCORE_BASEINFO score \n" ) ;
        sqlb.append(" LEFT JOIN drgs.MR_BASEINFO a on score.PMAININDEX  =a.PMAININDEX \n" ) ;     
        sqlb.append(" LEFT JOIN drgs.MR_IPINFO ipinfo on a.PMAININDEX = ipinfo.PMAININDEX \n" ) ;
        joinSqlByCondtion(sqlb,condition) ;
        sqlb.append(" LEFT JOIN ( SELECT detail.PMAININDEX,count(1) requiredCount \n" ) ;
        sqlb.append("   FROM drgs.MRQ_SCORE_DETAIL detail \n" ) ;
        sqlb.append("   where  detail.WEIGHT_CODE = 'A' \n" ) ;
        sqlb.append("   GROUP BY detail.PMAININDEX ) detail on detail.PMAININDEX = ipinfo.PMAININDEX \n" ) ;
        sqlb.append(" LEFT JOIN ( \n" ) ;
        sqlb.append("   SELECT detail.PMAININDEX,count(1) requiredCount \n" ) ;
        sqlb.append("   FROM  drgs.MRQ_DICT_RULES dictRule \n" ) ;
        sqlb.append("   LEFT JOIN DRGS.MRQ_DICT_DETAIL dictDetail on  dictDetail.Detail_Code = dictRule.Detail_Code \n" ) ;
        sqlb.append("    	and  dictDetail.SCORE_CODE in( select dictScore.Score_Code from drgs.mrq_dict_score dictScore where instr('"+hospName+"',dictScore.hosp_name)>0  ) \n" ) ;
        sqlb.append("   LEFT JOIN drgs.MRQ_SCORE_DETAIL detail  on dictRule.DETAIL_CODE = detail.DETAIL_CODE \n" ) ;
        sqlb.append("   where  dictRule.COMPLETE_FLAG = '1' and dictRule.Valid_Flag ='1' and dictDetail.Valid_Flag ='1' \n") ;
        sqlb.append("   GROUP BY detail.PMAININDEX \n" ) ;
        sqlb.append(" ) violation on  violation.PMAININDEX = ipinfo.PMAININDEX \n" ) ;
        sqlb.append("  LEFT JOIN (SELECT count(1) rc FROM  DRGS.MRQ_DICT_RULES dictRule join  DRGS.MRQ_DICT_DETAIL dictDetail on  dictDetail.Detail_Code = dictRule.Detail_Code ") ;
        sqlb.append("  		and  dictRule.SCORE_CODE in(select dictScore.Score_Code from drgs.mrq_dict_score dictScore where instr('"+hospName+"',dictScore.hosp_name)>0  )") ;
        sqlb.append("  		WHERE dictRule.COMPLETE_FLAG = '1' and dictRule.Valid_Flag ='1' and dictDetail.Valid_Flag ='1' ") ;
        sqlb.append("   	) dict ON 0=0 \n" ) ;
        sqlb.append("  LEFT JOIN (SELECT count(1) rcA FROM  DRGS.MRQ_DICT_RULES dictRule join  DRGS.MRQ_DICT_DETAIL dictDetail on  dictDetail.Detail_Code = dictRule.Detail_Code ") ;
        sqlb.append("  		and  dictRule.SCORE_CODE in(select dictScore.Score_Code from drgs.mrq_dict_score dictScore where instr('"+hospName+"',dictScore.hosp_name)>0  )") ;
        sqlb.append("  		WHERE dictRule.WEIGHT_CODE = 'A' and dictRule.Valid_Flag ='1' and dictDetail.Valid_Flag ='1' ") ;
        sqlb.append("    	) dictA ON 0=0 \n" ) ;
        sqlb.append(" WHERE 1=1 \n" ) ;
        String sql = sqlb.toString() ;
        // 条件替换
        sql = repalceSqlByConditon(sql,condition) ;
        List<Map<String,Object>> resultListF = drgsIndexCalApplication.excuteQueryForList(sql,condition) ;
        return resultListF == null ? new ArrayList<Map<String, Object>>() : resultListF ;
    }


    /**
     * @param condition
     * @return
     * @throws
     * @Description: 查询违规项
     * @author chenhanlin
     * @date 2018/8/9 13:43
     */
    @Override
    public List<Map<String, Object>> violationItems(Map<String, Object> condition) {
        if(condition.get("dateFrom")!=null && condition.get("dateTo") !=null){
            condition.put("dateFrom",DrgsIndex.formateDateFrom(condition.get("dateFrom")+"")) ;
            condition.put("dateTo",DrgsIndex.formateDateTo(condition.get("dateTo")+"")) ;
        }
        String hospName = mrqDictWeightApplication.getHospName();
        StringBuffer sqlb = new StringBuffer() ;
        sqlb.append(" SELECT  t1.RULE_CODE \"ruleCode\", t2.RULE_NAME  \"ruleName\",t2.SCORE_NAME \"scoreName\" ,t2.RULE_INTRODUCTION \"ruleIntroduction\",t2.WEIGHT_NAME \"weightName\" \n" ) ;
        sqlb.append(" ,t1.violationCaseCnt \"violationCaseCnt\" ,t3.totalMedicalRecord \"totalMedicalRecord\"  \n" ) ;
        sqlb.append(" FROM ( \n" ) ;
        sqlb.append(" SELECT violation.RULE_CODE \n" ) ;
        sqlb.append(" -- 违规病案数 \n" ) ;
        sqlb.append(" ,count(DISTINCT violation.pmainindex) violationCaseCnt \n" ) ;
        sqlb.append(" FROM  drgs.MR_BASEINFO a \n" ) ;
        sqlb.append("  LEFT JOIN drgs.MR_IPINFO ipinfo on a.PMAININDEX = ipinfo.PMAININDEX \n" ) ;
        joinSqlByCondtion(sqlb,condition) ;
        sqlb.append("  LEFT JOIN drgs.MRQ_VIOLATION violation on violation.PMAININDEX = ipinfo.PMAININDEX \n" ) ;
        sqlb.append(" WHERE 1=1  and violation.RULE_CODE is not null \n" ) ;
        sqlb.append(" GROUP BY violation.RULE_CODE \n" ) ;
        sqlb.append(" )t1 LEFT JOIN ( \n" ) ;
        sqlb.append("   SELECT DISTINCT dictRule.RULE_CODE,dictRule.SCORE_CODE,dictScore.SCORE_NAME,dictRule.RULE_NAME,dictRule.RULE_INTRODUCTION,dictWeight.WEIGHT_CODE, \n" ) ;
        sqlb.append(" dictWeight.WEIGHT_NAME FROM drgs.MRQ_DICT_RULES dictRule \n" ) ;
        sqlb.append(" RIGHT JOIN drgs.MRQ_DICT_SCORE dictScore on dictScore.SCORE_CODE = dictRule.SCORE_CODE and instr('"+hospName+"',dictScore.hosp_name)>0 \n" ) ;
        sqlb.append(" LEFT JOIN drgs.MRQ_DICT_WEIGHT dictWeight on dictWeight.WEIGHT_CODE = dictRule.WEIGHT_CODE \n" ) ;
        sqlb.append(" LEFT JOIN drgs.MRQ_DICT_DETAIL dictDetail  on dictRule.DETAIL_CODE = dictDetail.DETAIL_CODE \n" ) ;
        sqlb.append(" where  dictRule.Valid_Flag ='1' and dictDetail.Valid_Flag ='1'  \n" ) ;
        sqlb.append(" )t2 on t1.RULE_CODE = t2.RULE_CODE \n" ) ;
        sqlb.append("  LEFT JOIN ( \n"  ) ;
        sqlb.append(" SELECT count(score.PMAININDEX) totalMedicalRecord \n"  ) ;
        sqlb.append(" FROM  drgs.MR_BASEINFO a \n"  ) ;
        sqlb.append(" LEFT JOIN drgs.MR_IPINFO ipinfo on a.PMAININDEX = ipinfo.PMAININDEX \n"  ) ;
        sqlb.append(" RIGHT JOIN drgs.MRQ_SCORE_BASEINFO score on score.PMAININDEX = ipinfo.PMAININDEX \n"  ) ;
        joinSqlByCondtion(sqlb,condition) ;
        sqlb.append(" WHERE 1=1 \n"  ) ;
        sqlb.append(" )t3 on 0=0 \n" ) ;
        sqlb.append(" where t1.RULE_CODE is not null \n" ) ;
        sqlb.append(" ORDER BY t1.violationCaseCnt desc,t2.WEIGHT_CODE  \n ") ;
        String sql = sqlb.toString() ;
        // 条件替换
        sql = repalceSqlByConditon(sql,condition) ;
        List<Map<String,Object>> resultListF = null;
        try {
            resultListF = drgsIndexCalApplication.excuteQueryForList(sql,condition) ;
        } catch (Exception e) {
            resultListF = new ArrayList<>() ;
            e.printStackTrace();
        }
        return resultListF ;
    }

    /**
     * @param condition
     * @return
     * @throws
     * @Description: 查询违规科室/病区/医师
     * @author chenhanlin
     * @date 2018/8/9 13:43
     */
    @Override
    public List<Map<String, Object>> violationDeps(Map<String, Object> condition) {
        if(condition.get("dateFrom")!=null && condition.get("dateTo") !=null){
            condition.put("dateFrom",DrgsIndex.formateDateFrom(condition.get("dateFrom")+"")) ;
            condition.put("dateTo",DrgsIndex.formateDateTo(condition.get("dateTo")+"")) ;
        }
        StringBuffer sqlb = new StringBuffer() ;
        sqlb.append(" SELECT \n" ) ;
        sqlb.append(" tab1.ccode \"ccode\", tab1.ddesc \"ddesc\" \n" ) ;
        sqlb.append(" -- 违规 \n" ) ;
        sqlb.append(" , tab1.violationCaseCnt \"violationCaseCnt\" \n" ) ;
        sqlb.append(" -- 不合格 \n" ) ;
        sqlb.append(" , tab1.poor \"poor\" \n" ) ;
        sqlb.append(" -- 优秀 \n" ) ;
        sqlb.append(" , tab1.excellent \"excellent\" \n" ) ;
        sqlb.append(" -- 科室病例数 \n" ) ;
        sqlb.append(" , tab1.cnt \"cnt\" \n" ) ;
        sqlb.append(" -- 平均得分 \n" ) ;
        sqlb.append(" , tab1.avgScore \"avgScore\" \n" ) ;
        sqlb.append(" --总病例数 \n" ) ;
        sqlb.append(" ,tab2.totalMedicalRecord \"totalMedicalRecord\" \n" ) ;
        sqlb.append(" FROM ( -- 人数统计 \n" ) ;
        sqlb.append("  SELECT -obj1- \n" ) ;
        sqlb.append(" --违规 \n" ) ;
        sqlb.append(" ,count(violation.PMAININDEX) violationCaseCnt \n" ) ;
        sqlb.append(" -- 不合格 \n" ) ;
        sqlb.append(" , count((CASE WHEN score.RATING_LEVEL = '4' THEN score.pmainindex ELSE NULL END)) poor \n" ) ;
        sqlb.append(" -- 优秀 \n" ) ;
        sqlb.append(" , count((CASE WHEN score.RATING_LEVEL = '1' THEN score.pmainindex ELSE NULL END)) excellent \n" ) ;
        sqlb.append(" -- 总病例数 \n" ) ;
        sqlb.append(" , count((score.pmainindex)) cnt \n" ) ;
        sqlb.append(" ,round(avg(score.total_score), 2) avgScore \n" ) ;
        sqlb.append("  FROM drgs.MR_BASEINFO a \n" ) ;
        sqlb.append(" LEFT JOIN drgs.MR_IPINFO ipinfo ON a.PMAININDEX = ipinfo.PMAININDEX \n" ) ;
        sqlb.append(" RIGHT JOIN drgs.MRQ_SCORE_BASEINFO score ON score.PMAININDEX = ipinfo.PMAININDEX \n" ) ;
        joinSqlByCondtion(sqlb,condition) ;
        sqlb.append(" LEFT JOIN (select PMAININDEX FROM drgs.MRQ_VIOLATION VIOLATION WHERE 2=2 GROUP BY PMAININDEX) violation on violation.PMAININDEX = ipinfo.PMAININDEX \n" ) ;
        sqlb.append("  WHERE 1=1 \n" ) ;
        sqlb.append("  GROUP BY -grbyobj1- ) tab1  \n" ) ;
        sqlb.append("  LEFT JOIN ( \n"  ) ;
        sqlb.append(" SELECT count(score.PMAININDEX) totalMedicalRecord \n"  ) ;
        sqlb.append(" FROM  drgs.MR_BASEINFO a \n"  ) ;
        sqlb.append(" LEFT JOIN drgs.MR_IPINFO ipinfo on a.PMAININDEX = ipinfo.PMAININDEX \n"  ) ;
        sqlb.append(" RIGHT JOIN drgs.MRQ_SCORE_BASEINFO score on score.PMAININDEX = ipinfo.PMAININDEX \n"  ) ;
        joinSqlByCondtion(sqlb,condition) ;
        sqlb.append(" WHERE 1=1 \n"  ) ;
        sqlb.append(" )tab2 on 0=0 \n" ) ;
        sqlb.append(" WHERE tab1.violationCaseCnt>0 \n" ) ;
        sqlb.append(" ORDER BY tab1.violationcasecnt DESC, tab1.poor DESC \n" ) ;
        String sql = sqlb.toString() ;
        // 条件替换
        sql = repalceSqlByConditon(sql,condition) ;
        List<Map<String,Object>> resultListF = null;
        try {
            resultListF = drgsIndexCalApplication.excuteQueryForList(sql,condition) ;
        } catch (Exception e) {
            resultListF = new ArrayList<>() ;
            e.printStackTrace();
        }
        return resultListF ;
    }


    /**
     * @return
     * @throws
     * @Description: 查询各项的满分分数
     * @author chenhanlin
     * @date 2018/8/7 21:29
     */
    @Override
    public InvokeResult initializeFullScore() {
    	if(null == hospName || "".equals(hospName)){
    		hospName = mrqDictWeightApplication.getHospName();
    	}
        MrqScore mrqScore = mrqScoreFacade.initializeFullScore(hospName) ;
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("totalScore", mrqScore.getTotalScoreMap());
        map.put("partScore", mrqScore.getPartScoreMap());
        map.put("wholeClass", mrqScore.getWholeClass());
        map.put("partClass", mrqScore.getPartClass());
        return InvokeResult.success(map);
    }

    /**
     * @param condition
     * @return
     * @throws
     * @Description: 各项得分情况
     * @author chenhanlin
     * @date 2018/8/7 21:10
     */
    @Override
    public List<Map<String, Object>> queryScore(Map<String, Object> condition) {
    	if(null == hospName || "".equals(hospName)){
    		hospName = mrqDictWeightApplication.getHospName();
    	}
        if(condition.get("dateFrom")!=null && condition.get("dateTo") !=null){
            condition.put("dateFrom",DrgsIndex.formateDateFrom(condition.get("dateFrom")+"")) ;
            condition.put("dateTo",DrgsIndex.formateDateTo(condition.get("dateTo")+"")) ;
        }
        StringBuffer sqlb = new StringBuffer() ;
        sqlb.append(" select  total.score_code ,total.weight_code,round(avg(total.score),2) score \n") ;
        sqlb.append(" from drgs.MRQ_SCORE_TOTAL total \n") ;
        sqlb.append(" left join drgs.mrq_score_baseinfo base on total.pmainindex = base.pmainindex  \n") ;
        sqlb.append(" left join drgs.mr_ipinfo ipinfo on ipinfo.pmainindex = base.pmainindex  \n") ;
        joinSqlByCondtion(sqlb,condition) ;
        sqlb.append(" where total.score_code in ( \n") ;
        sqlb.append(" 		select ds.score_code from drgs.MRQ_DICT_SCORE ds where instr('"+hospName+"',ds.HOSP_NAME)>0 \n") ;
        sqlb.append(" )  and total.pmainindex in ( \n") ;
        sqlb.append(" 		select distinct a.pmainindex \n") ;
        sqlb.append("  		FROM  drgs.MR_BASEINFO a \n") ;
        sqlb.append("  		LEFT JOIN drgs.MR_IPINFO ipinfo on a.PMAININDEX = ipinfo.PMAININDEX \n") ; 
        sqlb.append(" 		WHERE   1=1  \n") ;
        sqlb.append(" ) group by total.score_code,total.weight_code \n") ;
        sqlb.append(" order by total.score_code,total.weight_code \n") ;
        
        String sql = repalceSqlByConditon(sqlb.toString(),condition) ;
        List<Map<String,Object>> resultListF = null;
        try {
        	resultListF = drgsIndexCalApplication.excuteQueryForList(sql,condition) ;
        } catch (Exception e) {
            resultListF = new ArrayList<>() ;
            e.printStackTrace();
        }
        return resultListF;
    }


    /**
     * @Description: 根据参数替换条件
     * @param
     * @return
     * @throws
     * @author chenhanlin
     * @date 2018/8/10 11:00
     */
    private String repalceSqlByConditon(String sql,Map<String,Object> condition) {
        String monitorType = MonitorResultUtil.object2String(condition.get("monitorType")) ;
        // 时间条件
        if(condition.get("dateFrom")!=null && condition.get("dateTo") !=null && condition.get("dateType") !=null ){
            String dateField = "" ;
            // 时间字段
            if("outDate".equals(condition.get("dateType"))){ // 出院日期
                dateField = "ipinfo.P00290000" ;
            } else if("pushDate".equals(condition.get("dateType"))) { // 推送日期
                dateField = "a.push_date" ;
            }
            sql = sql.replace("1=1", " 1=1 and to_char("+dateField+",'yyyy-mm-dd')  BETWEEN :dateFrom AND :dateTo \n ") ;
        }
        if(condition.get("hospCode") != null){
            sql = sql.replace("1=1" ," 1=1 and instr(:hospCode,a.p00010001)>0 \n ") ;
        }
        // 科室条件替换
        if(condition.get("pardepCode") != null){
            sql = sql.replace("1=1" ," 1=1 and ipinfo.P00300001 = :pardepCode \n ") ;
        }
        // 病区条件替换
        if(condition.get("ward") != null){
            sql = sql.replace("1=1" ," 1=1 and ipinfo.P00310000 = :ward \n ") ;
        }
        // 病区编码条件替换
        if(condition.get("parwardCode") != null){
            sql = sql.replace("1=1" ," 1=1 and ipinfo.P00310001 = :parwardCode \n ") ;
        }
        // 主诊医师条件替换
        if(condition.get("groupCode") != null && "clinic".equals(monitorType)){
            sql = sql.replaceAll("1=1", " 1=1 and ipinfo.P00601001=:groupCode  \n ");
        }
         // 主任医师条件替换
        if(condition.get("groupCode") != null && "protomedicus".equals(monitorType)){
            sql = sql.replaceAll("1=1", " 1=1 and ipinfo.P00600201=:groupCode  \n ");
        }
         // 主治医师条件替换
        if(condition.get("groupCode") != null && "physician".equals(monitorType)){
            sql = sql.replaceAll("1=1", " 1=1 and ipinfo.P00600301=:groupCode  \n ");
        }
         // 住院医师条件替换
        if(condition.get("groupCode") != null && "resident".equals(monitorType)){
            sql = sql.replaceAll("1=1", " 1=1 and ipinfo.P00600401=:groupCode  \n ");
        }

        // 质控规则条件
        if(condition.get("ruleCode") != null) {
            sql = sql.replace("2=2" ," 2=2 and violation.RULE_CODE = :ruleCode \n ") ;
        }
        // 根据monitorType 替换条件
        if ("dep".equals(monitorType)) {
            sql = sql.replaceAll("-obj1-", "dep.DEP_NAME ddesc, ipinfo.P00300001 ccode \n ");
            sql = sql.replaceAll("-grbyobj1-", "dep.DEP_NAME, ipinfo.P00300001 \n ");
            // 去除null的
            sql = sql.replaceAll("1=1", " 1=1 and ipinfo.P00600301 is not null \n ");
        } else if("ward".equals(monitorType)){
            sql = sql.replaceAll("-obj1-", "ipinfo.P00310001 ccode, ward.ward_desc ddesc \n ");
            sql = sql.replaceAll("-grbyobj1-", "ipinfo.P00310001, ward.ward_desc \n ");
            sql = sql.replaceAll("1=1", " 1=1 and ipinfo.P00310001 is not null \n ");
        } else if(docTypeList.contains(monitorType)) {
            IndexCal index = new IndexCal();
            index.setMonitorType(monitorType);
            sql = DrgsIndex.replaceDoctor( sql, index);
        }

        return sql ;
    }

    /**
     * @Description: 拼接sql
     * @param
     * @return
     * @throws
     * @author chenhanlin
     * @date 2018/8/12 20:55
     */
    private void joinSqlByCondtion(StringBuffer sqlb ,Map<String,Object> condition) {
        if ("dep".equals(condition.get("monitorType")) || StringUtils.hasLength(MonitorResultUtil.object2String(condition.get("pardepCode")))) {
            sqlb.append(" LEFT JOIN drgs.T_DEPARTMENT dep on dep.DEP_CODE = ipinfo.P00300001 \n" ) ;
        }
        if ("ward".equals(condition.get("monitorType")) || StringUtils.hasLength(MonitorResultUtil.object2String(condition.get("wardCode")))) {
            sqlb.append(" LEFT JOIN drgs.T_WARD ward ON ward.WARD_CODE = ipinfo.P00310001 \n" ) ;
        }
        if(docTypeList.contains(condition.get("monitorType")) || StringUtils.hasLength(MonitorResultUtil.object2String(condition.get("groupCode")))){
            sqlb.append(" -replace_t_doctor- \n ") ;
        }
    }

    /**
     * @Description: 质控前的数据准备
     * @param
     * @return
     * @throws
     * @author chenhanlin
     * @date 2018/7/31 16:40
     */
    @Override
    public void dataPreparation() {
    	if(null == hospName || "".equals(hospName)){
    		if(mrqDictWeightApplication==null){
    			mrqDictWeightApplication =(MrqDictWeightApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospMrqDictWeightApplicationImpl20181212");
            }
    		hospName = mrqDictWeightApplication.getHospName();
    	}
        // 生成满分的质控结果
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(mrqScoreFacade==null){
        	mrqScoreFacade =(MrqScoreFacade) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospMrqScoreFacadeImpl20181212");
        }
        MrqScore score  = mrqScoreFacade.initializeFullScore(hospName) ;
        scoreMap = score.getScoreMap();
        totalScoreMap = score.getTotalScoreMap();
        partScoreMap = score.getPartScoreMap();
        minScoreMap = score.getMinScoreMap();
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(mrqDictRulesFacade==null){
        	mrqDictRulesFacade =(MrqDictRulesFacade) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospMrqDictRulesFacadeImpl20181212");
        }
        rulesList = mrqDictRulesFacade.findAllMrqDictRules(hospName) ;
        // 规则完整性map
        for (MrqDictRules rule : rulesList) {
            ruleCompleteMap.put(rule.getRuleCode(),rule.getCompleteFlag()) ;
        }
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(mrqDictDetailApplication==null){
        	mrqDictDetailApplication =(MrqDictDetailApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsMrqDictDetailApplicationImpl20190103");
        }
        // 查询有效的质控规则
        ruleDetail = mrqDictDetailApplication.findDetailScore(hospName) ;
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(costSubApplication==null){
        	costSubApplication =(CostSubApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospCostSubApplicationImpl20181212");
        }
        // 费用子项查询
        List<CostSub> costSubList = costSubApplication.findAllCostSub() ;
        for (CostSub costSub:costSubList) {
            costSubMap.put(costSub.getCostSubcode(),costSub.getCostCodeQuality()) ;
        }
        // 字典值格式转换
        Map<String, List<Map<String, Object>>> sysDictionary = GlobalData.sysDictionary ;
        // 付费方式
        List<Map<String,Object>> paymentMapList = sysDictionary.get("P00020001") ;
        Map<String,String> paymentMap = new HashMap<>() ;
        if (paymentMapList!= null) {
            for(Map<String,Object> map:paymentMapList){
                paymentMap.put(MonitorResultUtil.object2String(map.get("DICVALUE")),MonitorResultUtil.object2String(map.get("DICDESC"))) ;
            }
        }
        QualityControlMedicalRecord.dictionaryMap.put("paymentMode",paymentMap) ;
        // 性别
        List<Map<String,Object>> genderListMap = sysDictionary.get("P00070001") ;
        Map<String,String> genderMap = new HashMap<>() ;
        if (genderListMap != null) {
            for(Map<String,Object> map:genderListMap){
                genderMap.put(MonitorResultUtil.object2String(map.get("DICVALUE")),MonitorResultUtil.object2String(map.get("DICDESC"))) ;
            }
        }
        QualityControlMedicalRecord.dictionaryMap.put("gender",genderMap) ;
        // 国籍
        List<Map<String,Object>> nationalityListMap = sysDictionary.get("P00100000") ;
        Map<String,String> nationalityMap = new HashMap<>() ;
        if (nationalityListMap != null) {
            for(Map<String,Object> map:nationalityListMap){
                nationalityMap.put(MonitorResultUtil.object2String(map.get("DICVALUE")),MonitorResultUtil.object2String(map.get("DICDESC"))) ;
            }
        }
        QualityControlMedicalRecord.dictionaryMap.put("nationality",nationalityMap) ;
        // 民族
        List<Map<String,Object>> nationListMap = sysDictionary.get("P0015000") ;
        Map<String,String> nationMap = new HashMap<>() ;
        if (nationListMap != null) {
            for(Map<String,Object> map:nationListMap){
                nationMap.put(MonitorResultUtil.object2String(map.get("DICVALUE")),MonitorResultUtil.object2String(map.get("DICDESC"))) ;
            }
        }
        QualityControlMedicalRecord.dictionaryMap.put("nation",nationMap) ;
        isPrepared = true ;
    }

    @Override
    public void batchMedicalRecordQualityAnalysis(Map<String,Object> condition) {

        if(condition.get("dateFrom")!=null && condition.get("dateTo") !=null){
            condition.put("dateFrom",DrgsIndex.formateDateFrom(condition.get("dateFrom")+"")) ;
            condition.put("dateTo",DrgsIndex.formateDateTo(condition.get("dateTo")+"")) ;
        }
        // 查询数据总量，进行分页查询
        String sql = " SELECT  count (1) FROM drgs.MR_BASEINFO a  LEFT JOIN drgs.MR_IPINFO ipinfo ON a.PMAININDEX = ipinfo.PMAININDEX WHERE 1=1 \n" ;
        String operateContent = "";
        // 时间条件
        if(condition.get("dateFrom")!=null && condition.get("dateTo") !=null){
            String dateField = "" ;
            // 时间字段
            if("outDate".equals(condition.get("dateType"))){ // 出院日期
                dateField = "ipinfo.P00290000" ;
                operateContent = "出院日期";
            } else if("pushDate".equals(condition.get("dateType"))) { // 推送日期
                dateField = "a.push_date" ;
                operateContent = "推送日期";
            }
            sql = sql.replace("1=1", " 1=1 and to_char("+dateField+",'yyyy-mm-dd')  BETWEEN :dateFrom AND :dateTo ") ;
        }
        if(condition.get("hospCode") != null){
            sql = sql.replace("1=1" ," 1=1 and instr(:hospCode,a.p00010001)>0 ") ;
        }
        statusMap.put("desc", "正在查询病例信息");
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(drgsIndexCalApplication==null){
        	drgsIndexCalApplication =(DrgsIndexCalApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsIndexCalApplicationImpl");
        }
        Integer totalCount = drgsIndexCalApplication.executeQueryForInt(sql,condition) ;
        statusMap.put("totalCount", MonitorResultUtil.object2String(totalCount)) ;      
        int pageSize = MonitorResultUtil.objectToDouble(condition.get("pageSize")).intValue() ;
        int batchNum = 1 ;
        if (totalCount != null) {
            batchNum = totalCount % pageSize > 0 ? totalCount / pageSize + 1 : totalCount / pageSize; // 处理批次
        }
        statusMap.put("batchSize", pageSize+"");
        statusMap.put("batchNum",batchNum+"") ;
        statusMap.put("nowCount","0");
        // 分批处理
        for (int i =1; i<=batchNum ; i++) {
            condition.put("pageNo",i) ;
            statusMap.put("batch",i+"") ;
            try {
                findMedicalRecordQuality(condition) ;
            } catch (Exception e) {
                statusMap.put("errmsg"+i,"第"+i+"批次处理有错误，请注意查看日志 \n") ;
                e.printStackTrace();
            }
        }
        // 清空状态信息
        statusMap.put("message","") ;
        // 等待前面信息更新
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        statusMap.clear();
        isPrepared = false ;
        //记录操作日志
        operateContent = "病案质控--"+DrgsIndex.formateDateFrom(null)+"-- 名称："+CurrentUser.getName()+",  账号："+CurrentUser.getUserAccount()+",  角色："+CurrentUser.getRoleName()
    	+",  操作：质控开始日期为："+condition.get("dateFrom")+"  结束日期为："+condition.get("dateTo")+" 日期类型为： "+operateContent+"  共质控  "+totalCount+" 条数据\r\n";
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(mrqDictDetailFacade==null){
        	mrqDictDetailFacade =(MrqDictDetailFacade) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospMrqDictDetailFacadeImp20180807");
        }
        mrqDictDetailFacade.recordOperationLog(operateContent);
    }

    /**
     * 功能描述: 质控首页数据-单个病例
     *
     * @param medicalRecordQuality
     * @param:
     * @return:
     * @auther: chenhanlin
     * @date: 2018/7/25 11:10
     */
    @Override
    public void singleMedicalRecordQualityAnalysis(MedicalRecordQuality medicalRecordQuality) {
        if(isPrepared == false) {
            dataPreparation();
        }
        medicalRecordQualityAnalysis(medicalRecordQuality);
    }

    /**
     * @Description: 首页质控方法，质控单条数据
     * @param
     * @return
     * @throws
     * @author chenhanlin
     * @date 2018/8/2 21:47
     */
    public void medicalRecordQualityAnalysis(MedicalRecordQuality medicalRecordQuality) {
        MrqScore msTmp = new MrqScore();
        String pmainindex = medicalRecordQuality.getIpinfo().getPmainIndex();
        msTmp.setPmainIndex(pmainindex);
        msTmp.setDepCode(medicalRecordQuality.getIpinfo().getP00300001());
        msTmp.setOrgCode(medicalRecordQuality.getBaseInfo().getP00010001());
        msTmp.setOutDate(medicalRecordQuality.getIpinfo().getP00290000()); 
        //因为scoreMap是对象类型，直接传引用，对象的数据可能被修改，所以要深度复制以避免值被修改
        List<Map<String, Object>> scoreMapNew = (List<Map<String, Object>>) DrgsIndex.copyPropertiesObj(scoreMap);
        msTmp.setScoreMap(scoreMapNew);
        Map<String,Double> totalScoreMapNew = (Map<String, Double>) DrgsIndex.copyPropertiesObj(totalScoreMap);
        msTmp.setTotalScoreMap(totalScoreMapNew);
        Map<String,Double> partScoreMapNew = (Map<String, Double>) DrgsIndex.copyPropertiesObj(partScoreMap);
        msTmp.setPartScoreMap(partScoreMapNew);
        Map<String,Double> minScoreMapNew = (Map<String, Double>) DrgsIndex.copyPropertiesObj(minScoreMap);
        msTmp.setMinScoreMap(minScoreMapNew);
        medicalRecordQuality.setMrqScore(msTmp);
        medicalRecordQuality.setMrqViolationList(new ArrayList<MrqViolation>());
        medicalRecordQuality.setMrqScoreDetailList(new ArrayList<MrqScoreDetail>());

        //  调用质控规则生成违规数据项目
        String methodName;
        // 反射
        Method method; // 方法
        Class[] argsType = {MedicalRecordQuality.class, MrqDictRules.class}; // 入参类型
        Object[] args = new Object[2]; // 入参
        try {
            for (MrqDictRules rule : rulesList) {
                methodName = dealMethodName(rule.getRuleCode());
                try {
                    method = qualityControl.getClass().getDeclaredMethod(methodName, argsType);
                    method.setAccessible(true); // 压制Java对访问修饰符的检查
                    // 设置入参
                    args[0] = medicalRecordQuality;
                    args[1] = rule;
                    // 调用方法
                    method.invoke(qualityControl, args);
                } catch (NoSuchMethodException e) {
                    System.err.println("没有该方法 : " + methodName);
                    logger.error("没有该方法 : " + methodName);
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                    logger.error(methodName);
                }
            }
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        //  根据项目的分数生成违规项目的扣分明细
        List<MrqViolation> mrqViolationList = medicalRecordQuality.getMrqViolationList();
        // 合并违规项的分数
        Map<String, Double> pointsMap = new HashMap<>();
        Map<String, Double> detailMap = new HashMap<>();
        for (MrqViolation mrqViolation : mrqViolationList) {
        	//BASICINFO-C-Gender
        	String detailCode = mrqViolation.getDetailCode();
        	//0.5
            Double detailScore = MonitorResultUtil.objectToDouble(detailMap.get(detailCode));
            //BASICINFO-C-Gender,  3
        	detailMap.put(detailCode, detailScore + mrqViolation.getRuleScore());
        }
        Iterator dmP = detailMap.entrySet().iterator();
        while (dmP.hasNext()) {
            Map.Entry entry = (Map.Entry) dmP.next();
            String detaiCode = MonitorResultUtil.object2String(entry.getKey());
            //分项实际扣分
            Double score = MonitorResultUtil.objectToDouble(entry.getValue());
            //分项最高扣分
            //ruleDetail:  key :BASICINFO-A-BirthWeight    value: 4.0
            Double detailScore = MonitorResultUtil.objectToDouble(ruleDetail.get(detaiCode));
            if(score < detailScore){//实际扣分 < 最高扣分
            	pointsMap.put(detaiCode, score);
            }else{
            	pointsMap.put(detaiCode, detailScore);
            }
        }
        List<MrqScoreDetail> mrqScoreDetailList = medicalRecordQuality.getMrqScoreDetailList();
        Iterator iterP = pointsMap.entrySet().iterator();
        // 循环扣分项
        while (iterP.hasNext()) {
            // 保存质控项分数
            MrqScoreDetail mrqScoreDetail = new MrqScoreDetail();
            Map.Entry entry = (Map.Entry) iterP.next();
            String detaiCode = MonitorResultUtil.object2String(entry.getKey());
            Double score = MonitorResultUtil.objectToDouble(entry.getValue());
            mrqScoreDetail.setDetailCode(detaiCode);//BASICINFO-C-Gender
            mrqScoreDetail.setDetailDeduction(score);//1  实际扣分1分
            mrqScoreDetail.setPmainIndex(pmainindex);
            String[] detailCodeArray = detaiCode.split("-");
            mrqScoreDetail.setScoreCode(detailCodeArray.length > 0 ? detailCodeArray[0] : "");// BASICINFO
            mrqScoreDetail.setWeightCode(detailCodeArray.length > 1 ? detailCodeArray[1] : "");// C
            mrqScoreDetail.setId(pmainindex + "-" + detaiCode);
            mrqScoreDetail.setTotalId(pmainindex + "-" +(detailCodeArray.length > 0 ? detailCodeArray[0] : "")+"-" +(detailCodeArray.length > 1 ? detailCodeArray[1] : ""));
            mrqScoreDetailList.add(mrqScoreDetail);
        }
        medicalRecordQuality.setMrqScoreDetailList(mrqScoreDetailList);


        //  用总分减去扣分项合计,更新病例的最终得分。
        // 统计违规项的分数
        Map<String, Double> pointSumMap = new HashMap<>();
        for (MrqScoreDetail mrqScoreDetail : mrqScoreDetailList) {
            String scoreCode = mrqScoreDetail.getScoreCode();//BASICINFO
            String weightCode = mrqScoreDetail.getWeightCode();//A
            // 不同权重统计
            Double dWeight = MonitorResultUtil.objectToDouble(pointSumMap.get(scoreCode +"@@"+ weightCode ));
            // pointSumMap.put("BASICINFO@@A",10)   BASICINFO分类A的最终扣分为 10分
            pointSumMap.put(scoreCode +"@@"+ weightCode , dWeight + mrqScoreDetail.getDetailDeduction());
        }

        // 最终得分
        MrqScore mrqScore = medicalRecordQuality.getMrqScore();
        //分类满分明细  partScoreMap("BASICINFO@@A", 8.0);
        Map<String,Double> partScoreMap = mrqScore.getPartScoreMap();
        //分类保底得分明细
        Map<String,Double> minScoreMap = mrqScore.getMinScoreMap();
        if(null != partScoreMap && partScoreMap.size()>0){
        	Map<String,Double> finalScoreMap = new HashMap<String,Double>();
        	Iterator psm = partScoreMap.entrySet().iterator();
            // 循环扣分项,用满分减去扣分项,保存结果
            while (psm.hasNext()) {
            	Map.Entry entry = (Map.Entry) psm.next();
            	//BASICINFO@@A
            	String key = (String)entry.getKey();
            	//8.0
            	Double score = (Double)entry.getValue();
            	Double resultScore = 0.0 ;//最终得分
            	if (pointSumMap.containsKey(key)) {//如果有扣分项
            		//满分为8 ，实际扣分 可能为 0，可能为4，可能为10
            		Double deductScore = pointSumMap.get(key);
            		//如果 满分 > 扣分
            		if(score > deductScore ){
            			resultScore = score - deductScore;
            			if(minScoreMap.containsKey(key)){
            				//最低得分 默认值为0
            				Double minScore = minScoreMap.get(key);
            				//resultScore 最终得分, minScore 保底得分
            				resultScore = resultScore > minScore ? resultScore : minScore ;
            			}
            			//防止出现 扣分deductScore为负数的情况
//            			resultScore = resultScore > score ? score : resultScore ;
            		}else{
            			//如果 满分 <= 扣分 ,则得0分
            			resultScore = 0.0 ;
            		}
                }else{//如果没有扣分项则得满分
                	resultScore = score ;
                }
            	//最终得分
            	finalScoreMap.put(key, resultScore);
            }
            mrqScore.setCheckScoreMap(finalScoreMap);
            
            //计算总分
            double totalScore = 0;
            boolean isLowLevel = false;
            if(null != finalScoreMap && finalScoreMap.size()>0){
                Iterator fsMap = finalScoreMap.entrySet().iterator();
                // 评定等级
                while (fsMap.hasNext()) {
                	Map.Entry entry = (Map.Entry) fsMap.next();
                	Double score = (Double)entry.getValue();
                	totalScore = totalScore + score ;
                	// A类有扣分项，评定等级即为差
                	String key = (String)entry.getKey();
                	String[] keyList = key.split("@@");
                	if(null != keyList && keyList.length>1 && "A".equals(keyList[1]) ){
                		if( score <  partScoreMap.get(key) ){
                			isLowLevel = true;
                		}
                	}               	
                }
                // 评定等级:1-优；2-良；3-中；4-差—— ≥97 && 不出现A类项错误 = 优； 90-96 && 不出现A类项错误 = 良； 75-89 && 不出现A类项错误 = 中； <75 = 差
                // A类有扣分项，评定等级即为差
                if(isLowLevel){
                	mrqScore.setRatingLevel("4");
                }else{
                    if (totalScore >= 97) {
                        mrqScore.setRatingLevel("1");
                    } else if (totalScore < 97 && totalScore >= 90) {
                        mrqScore.setRatingLevel("2");
                    } else if (totalScore < 90 && totalScore >= 75) {
                        mrqScore.setRatingLevel("3");
                    } else {
                        mrqScore.setRatingLevel("4");
                    }
                }
            }
            mrqScore.setTotalScore(totalScore);
        }
        // 完整性校验 : 1 完整；0 不完整
        String complateFlag = integrityVerification(medicalRecordQuality);
        mrqScore.setCompleteFlag(complateFlag);
        Date date = new Date();
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd :hh:mm:ss");
        dateFormat.format(date) ;
        mrqScore.setCheckDate(date) ;
        medicalRecordQuality.setMrqScore(mrqScore);
        //处理一下详细扣分规则列表，存数据的时候同一个PmainIndex只允许存一条规则名称
        //  根据项目的分数生成违规项目的扣分明细
        List<MrqViolation> mrqViolationListOld = medicalRecordQuality.getMrqViolationList();
        List<MrqViolation> mrqViolationListNew = new ArrayList<MrqViolation>();
        // 去除重复项
        Map<String, MrqViolation> oldMap = new HashMap<>();
        for (MrqViolation mrqViolation : mrqViolationListOld) {
        	oldMap.put(pmainindex+"-"+mrqViolation.getRuleCode(), mrqViolation);
        }
        Iterator oMsm = oldMap.entrySet().iterator();
        // 循环扣分项,用满分减去扣分项,保存结果
        while (oMsm.hasNext()) {
        	Map.Entry entry = (Map.Entry) oMsm.next();
        	MrqViolation value = (MrqViolation)entry.getValue();
        	if(null != value){
        		mrqViolationListNew.add(value);
        	}
        }
        medicalRecordQuality.setMrqViolationList(mrqViolationListNew);
    }

    /**
     *
     * @Description: 完整性校验
     * @param:
     * @return:
     * @auther: chenhanlin
     * @date: 2018/8/2 10:36
     */
    private String integrityVerification(MedicalRecordQuality medicalRecordQuality) {
        List<MrqViolation> mrqViolationList = medicalRecordQuality.getMrqViolationList() ;
        for (MrqViolation mrqViolation:mrqViolationList) {
            if ("1".equals(ruleCompleteMap.get(mrqViolation.getRuleCode()))) {
                return "0" ;
            }
        }
        return "1" ;
    }


    @Override
    public void findMedicalRecordQuality(Map<String,Object> condition) {
        if(isPrepared == false ){
            dataPreparation() ;
        }
        // 住院信息
        statusMap.put("message","正在查询住院信息") ;
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(mrIpInfoApplication==null){
        	mrIpInfoApplication =(MrIpInfoApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospMrIpInfoApplicationImpl20181212");
        }
        List<MrIpInfo> ipInfoList = mrIpInfoApplication.queryMrIpInfoByCondition(condition) ;
        statusMap.put("message","正在查询基本信息") ;
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(mrBaseInfoApplication==null){
        	mrBaseInfoApplication =(MrBaseInfoApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospMrBaseInfoApplicationImpl20181212");
        }
        // 基本信息
        List<MrBaseInfo> mrBaseInfoList = mrBaseInfoApplication.queryMrBaseInfoByCondition(condition) ;
        Map<String,MrBaseInfo> mrBaseInfoMap = new HashMap<>() ;
        for(MrBaseInfo mrBaseInfo : mrBaseInfoList) {
            mrBaseInfoMap.put(mrBaseInfo.getPmainIndex(),mrBaseInfo) ;
        }
        // 手术信息
        statusMap.put("message","正在查询手术信息") ;
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(mrOperationApplication==null){
        	mrOperationApplication =(MrOperationApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospMrOperationApplicationImpl20181212");
        }
        List<MrOperation> mrOperationList = mrOperationApplication.queryMrOperationByCondition(condition) ;
        Map<String,List<MrOperation>> mrOperationMap = new HashMap<>() ;
        for(MrOperation mrOperation : mrOperationList) {
            String pmainindex = mrOperation.getPmainIndex() ;
            if (mrOperationMap.containsKey(pmainindex)) {
                mrOperationMap.get(pmainindex).add(mrOperation) ;
            } else {
                List<MrOperation> mrOperationListT = new ArrayList<>() ;
                mrOperationListT.add(mrOperation) ;
                mrOperationMap.put(mrOperation.getPmainIndex(),mrOperationListT) ;
            }

        }
        // 诊断信息
        statusMap.put("message","正在查询诊断信息") ;
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(mrDiagnoseApplication==null){
        	mrDiagnoseApplication =(MrDiagnoseApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospMrDiagnoseApplicationImpl20181212");
        }
        List<MrDiagnose> mrDiagnoseList = mrDiagnoseApplication.queryMrDiagnosesByCondition(condition) ;
        Map<String,List<MrDiagnose>> mrDiagnoseMap = new HashMap<>() ;
        for(MrDiagnose mrDiagnose : mrDiagnoseList) {
            String pmainindex = mrDiagnose.getPmainIndex() ;
            if (mrDiagnoseMap.containsKey(pmainindex)) {
                mrDiagnoseMap.get(pmainindex).add(mrDiagnose) ;
            } else {
                List<MrDiagnose> mrDiagnoseListT = new ArrayList<>() ;
                mrDiagnoseListT.add(mrDiagnose) ;
                mrDiagnoseMap.put(mrDiagnose.getPmainIndex(),mrDiagnoseListT) ;
            }

        }
        // 附页信息
        statusMap.put("message","正在查询附页信息") ;
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(mrAppendPageApplication==null){
        	mrAppendPageApplication =(MrAppendPageApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospMrAppendPageApplicationImpl20181212");
        }
        List<MrAppendPage> appendPageList = mrAppendPageApplication.queryMrAppendPageByCondition(condition) ;
        Map<String,MrAppendPage> mrAppendPageMap = new HashMap<>() ;
        for(MrAppendPage mrAppendPage : appendPageList) {
            mrAppendPageMap.put(mrAppendPage.getPmainIndex(),mrAppendPage) ;
        }
        // 费用信息
        statusMap.put("message","正在查询费用信息") ;
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(mrExpenseApplication==null){
        	mrExpenseApplication =(MrExpenseApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsHospMrExpenseApplicationImpl20181212");
        }
        List<MrExpense> mrExpenseList = mrExpenseApplication.queryMrExpenseByCondition(condition) ;
        Map<String,Map<String,Double>> mrExpenseMap = new HashMap<>() ;
        for(MrExpense mrExpense : mrExpenseList) {
            String pmainindex = mrExpense.getPmainIndex() ;
            if (mrExpenseMap.containsKey(pmainindex)) {
                mrExpenseMap.get(pmainindex).put(costSubMap.get(mrExpense.getPe0101()),mrExpense.getPe0200()) ;
            } else {
                Map<String,Double> map = new HashMap<>() ;
                map.put(costSubMap.get(mrExpense.getPe0101()),mrExpense.getPe0200()==null?0:mrExpense.getPe0200()) ;
                mrExpenseMap.put(pmainindex,map) ;
            }
        }
        List<MedicalRecordQuality> medicalRecordQualityList = new ArrayList<>() ;
        int  count =  0 ;
        statusMap.put("message","正在质控") ;
        for (MrIpInfo mrIpInfo: ipInfoList) {
            count++ ;
            System.err.println("=====================当前是第"+statusMap.get("batch")+"批的第"+count+"条数据,共"+statusMap.get("totalCount")+"条数据");
            String pmainindex = mrIpInfo.getPmainIndex();
            MedicalRecordQuality medicalRecordQuality = new MedicalRecordQuality() ;
            medicalRecordQuality.setBaseInfo(mrBaseInfoMap.get(pmainindex));
            medicalRecordQuality.setIpinfo(mrIpInfo);
            medicalRecordQuality.setOperation(mrOperationMap.get(pmainindex));
            medicalRecordQuality.setDiagnose(mrDiagnoseMap.get(pmainindex));
            medicalRecordQuality.setExpenseMap(mrExpenseMap.get(pmainindex));
            medicalRecordQuality.setMrAppendPage(mrAppendPageMap.get(pmainindex));
            medicalRecordQualityAnalysis(medicalRecordQuality) ;
            medicalRecordQualityList.add(medicalRecordQuality) ;
            // 累计处理
            statusMap.put("nowCount", (Integer.valueOf(statusMap.get("nowCount"))+1)+"" );
            // 某批次的第几条数据
            statusMap.put("batchCount", count+"");
        }
        statusMap.put("message","正在保存质控结果") ;
        saveMedicalRecordQualityList(medicalRecordQualityList,condition);
    }

    /**
     * @param medicalRecordQuality
     * @return
     * @throws
     * @Description: 质控病例
     * @author chenhanlin
     * @date 2018/7/28 17:49
     */
    @Override
    public void qualityMedicalRecored(MedicalRecordQuality medicalRecordQuality) {
        statusMap.put("message","正在保存信息") ;
        // 质控病案首页数据
        medicalRecordQualityAnalysis(medicalRecordQuality);
        String pmainindex = medicalRecordQuality.getIpinfo().getPmainIndex() ;
        // 首页质控删除
        deleteMedicalRecordQualityByPmainindex(pmainindex);
        // 保存质控结果
        saveMedicalRecordQuality(medicalRecordQuality);
    }


    /**
     * @param medicalRecordQuality
     * @return
     * @throws
     * @Description: 保存病案的质控结果
     * @author chenhanlin
     * @date 2018/7/28 17:45
     */
    @Override
    public void saveMedicalRecordQuality(MedicalRecordQuality medicalRecordQuality) {
        MrqScore mrqScore = medicalRecordQuality.getMrqScore() ;
        List<MrqViolation> mrqViolationList =  medicalRecordQuality.getMrqViolationList() ;
        List<MrqScoreDetail> mrqScoreDetailList = medicalRecordQuality.getMrqScoreDetailList() ;
        mrqScoreApplication.saveMrqScore(mrqScore);
        for (MrqViolation mrqViolation:mrqViolationList) {
            mrqViolationApplication.createMrqViolation(mrqViolation);
        }
        for (MrqScoreDetail mrqScoreDetail : mrqScoreDetailList) {
            mrqScoreDetailApplication.createMrqScoreDetail(mrqScoreDetail);
        }
    }

    /**
     * @param pmainindex
     * @Description: 根据病例pmainindex删除相应的质控记录
     * @param:
     * @return:
     * @auther: chenhanlin
     * @date: 2018/7/28 17:41
     */
    @Override
    public void deleteMedicalRecordQualityByPmainindex(String pmainindex) {
        // 删除病例的质控记录
        mrqScoreApplication.removeMrqScoreByPmainIndex(pmainindex);
        mrqScoreDetailApplication.removeMrqScoreDetailByPmainIndex(pmainindex);
        mrqViolationApplication.removeMrqViolationByPmainIndex(pmainindex);
    }


    /**
     * @Description: 处理方法名 rule_Method
     * @param
     * @return
     * @throws
     * @author chenhanlin
     * @date 2018/8/2 10:09
     */
    private static String dealMethodName(String str) {
        if(StringUtils.hasLength(str)){
        	String s = str.toLowerCase();
        	if(0 == s.indexOf("rule-")){
        		str = "rule"+StringUtils.toUpperFirstChar(str.substring(5)) ;
        	}
        }
        return str;
    }

    /**
     * @Description:批量保存质控结果
     * @param
     * @return
     * @throws
     * @author chenhanlin
     * @date 2018/7/29 10:51
     */
//    @Transactional
    private void saveMedicalRecordQualityList(List<MedicalRecordQuality> medicalRecordQualityList,Map<String,Object> condition) {
        // 分页sql
        String pageSqlBody = " ( SELECT * FROM (SELECT PAGERESULT.*, ROWNUM RN FROM ( SELECT a.PMAININDEX FROM  drgs.MR_BASEINFO a LEFT JOIN drgs.MR_IPINFO ipinfo ON a.PMAININDEX = ipinfo.PMAININDEX WHERE   1=1  ORDER BY ipinfo.PMAININDEX desc) PAGERESULT ) WHERE rn>(:pageNo-1)*:pageSize and rn <=:pageNo*:pageSize )page" ;
        // 时间条件
        if(condition.get("dateFrom")!=null && condition.get("dateTo") !=null){
            String dateField = "" ;
            // 时间字段
            if("outDate".equals(condition.get("dateType"))){ // 出院日期
                dateField = "ipinfo.P00290000" ;
            } else if("pushDate".equals(condition.get("dateType"))) { // 推送日期
                dateField = "a.push_date" ;
            }
            pageSqlBody = pageSqlBody.replace("1=1", " 1=1 and to_char("+dateField+",'yyyy-mm-dd')  BETWEEN :dateFrom AND :dateTo ") ;
        }

        if(condition.get("hospCode") != null){
            pageSqlBody = pageSqlBody.replace("1=1" ," 1=1 and instr(:hospCode,a.p00010001)>0 ") ;
        }

        String sqlDeleteMrqScoreBaseInfo = "delete FROM  drgs.MRQ_SCORE_BASEINFO score where exists(select 1 from "+pageSqlBody+" where  page.PMAININDEX = score.PMAININDEX) \n" ;
        String sqlDeleteMrqScoreTotal = "delete FROM  drgs.MRQ_SCORE_TOTAL score where exists(select 1 from "+pageSqlBody+" where  page.PMAININDEX = score.PMAININDEX) \n" ;
        String sqlDeleteViolation = "delete FROM  drgs.MRQ_SCORE_DETAIL detail where exists(select 1 from "+pageSqlBody+" where  page.PMAININDEX = detail.PMAININDEX) \n" ;
        String sqlDeleteScoreDetail = "delete FROM drgs.MRQ_VIOLATION violation where exists(select 1 from "+pageSqlBody+" where  page.PMAININDEX = violation.PMAININDEX) \n" ;
        //定时任务使用java反射时必须重新实例化该接口，bean括号里面填impl实例上面的@Name括号里面的内容
        if(drgsIndexCalApplication==null){
        	drgsIndexCalApplication =(DrgsIndexCalApplication) ContextLoader.getCurrentWebApplicationContext().getBean("drgsIndexCalApplicationImpl");
        }
        // 删除质控相关表数据
        drgsIndexCalApplication.excuteUpdate(sqlDeleteMrqScoreBaseInfo,condition) ;
        drgsIndexCalApplication.excuteUpdate(sqlDeleteMrqScoreTotal,condition) ;
        drgsIndexCalApplication.excuteUpdate(sqlDeleteViolation,condition) ;
        drgsIndexCalApplication.excuteUpdate(sqlDeleteScoreDetail,condition) ;

        List<MrqScore> mrqScoreBaseInfoList  = new ArrayList<>() ;
        List<MrqScore> mrqScoreTotalList  = new ArrayList<>() ;
        List<MrqViolation> mrqViolationListAll = new ArrayList<>() ;
        List<MrqScoreDetail> mrqScoreDetailListAll = new ArrayList<>() ;
        for(MedicalRecordQuality medicalRecordQuality : medicalRecordQualityList){         
            mrqViolationListAll.addAll(medicalRecordQuality.getMrqViolationList() ) ;
            mrqScoreDetailListAll.addAll(medicalRecordQuality.getMrqScoreDetailList() ) ;
            MrqScore mrqScore = medicalRecordQuality.getMrqScore() ;
            MrqScore baseInfoScore = new MrqScore();            
            //PMAININDEX,ORG_CODE,DEP_CODE,RATING_LEVEL,CHECK_DATE,OUT_DATE,COMPLETE_FLAG,TOTAL_SCORE
            baseInfoScore.setPmainIndex(mrqScore.getPmainIndex());
            baseInfoScore.setOrgCode(mrqScore.getOrgCode());
            baseInfoScore.setDepCode(mrqScore.getDepCode());
            baseInfoScore.setRatingLevel(mrqScore.getRatingLevel());
            baseInfoScore.setCheckDate(mrqScore.getCheckDate());
            baseInfoScore.setOutDate(mrqScore.getOutDate());
            baseInfoScore.setCompleteFlag(mrqScore.getCompleteFlag());
            baseInfoScore.setTotalScore(mrqScore.getTotalScore());
            mrqScoreBaseInfoList.add(baseInfoScore);
            //
            Map<String,Double> checkScoreMap = mrqScore.getCheckScoreMap();
            if(null != checkScoreMap && checkScoreMap.size()>0){
                Iterator csMap = checkScoreMap.entrySet().iterator();
                while (csMap.hasNext()) {
                	Map.Entry entry = (Map.Entry) csMap.next();
                	String key = (String)entry.getKey();
                	Double score = (Double)entry.getValue();
                    String[] keyList = key.split("@@");
                    if( null != keyList && keyList.length>1){
                        MrqScore totalScore = new MrqScore();
                        totalScore.setPmainIndex(mrqScore.getPmainIndex());
                        totalScore.setScoreCode(keyList[0]);
                        totalScore.setWeightCode(keyList[1]);
                        totalScore.setScore(score);
                        totalScore.setId(mrqScore.getPmainIndex()+"-"+keyList[0]+"-"+keyList[1]);
                        mrqScoreTotalList.add(totalScore);
                    }
                }
            }
        }

        // 插入数据
        String sqlInsertBaseInfoScore = "INSERT  INTO drgs.MRQ_SCORE_BASEINFO (PMAININDEX,ORG_CODE,DEP_CODE,RATING_LEVEL,CHECK_DATE,OUT_DATE,COMPLETE_FLAG,TOTAL_SCORE)  VALUES (:pmainIndex,:orgCode,:depCode,:ratingLevel,:checkDate,:outDate,:completeFlag,:totalScore)" ;
        String sqlInsertTotalScore = "INSERT  INTO drgs.MRQ_SCORE_TOTAL (ID,PMAININDEX,SCORE_CODE,WEIGHT_CODE,SCORE)  VALUES (:id,:pmainIndex,:scoreCode,:weightCode,:score)" ;
        String sqlInsertViolation = "INSERT  INTO drgs.MRQ_VIOLATION (ID,PMAININDEX,SCORE_CODE,WEIGHT_CODE,RULE_CODE)  VALUES (:id,:pmainIndex,:scoreCode,:weightCode,:ruleCode)" ;
        String sqlInsertScoreDetail = "INSERT  INTO drgs.MRQ_SCORE_DETAIL (ID,PMAININDEX,SCORE_CODE,WEIGHT_CODE,DETAIL_CODE,DETAIL_DEDUCTION) VALUES (:id,:pmainIndex,:scoreCode,:weightCode,:detailCode,:detailDeduction)" ;
        drgsIndexCalApplication.batchUpdate(sqlInsertBaseInfoScore,mrqScoreBaseInfoList) ;
        drgsIndexCalApplication.batchUpdate(sqlInsertTotalScore,mrqScoreTotalList) ;
        drgsIndexCalApplication.batchUpdate(sqlInsertViolation,mrqViolationListAll) ;
        drgsIndexCalApplication.batchUpdate(sqlInsertScoreDetail,mrqScoreDetailListAll) ;
    }
    /**
     * @Description:  查询运行状态参数
     * @param
     * @return
     * @throws
     * @author qiaoyilong
     * @date 2018/8/14 16:43
     */
    @Override
    public Map<String,String> getBatchAnalysisParameter(){
    	return statusMap;
    }
    /**
     * @Description:  初始化大类和小类信息
     * @return 数据实例 key: BASICIFO, value: Map['A','B','C','D']
     */
    private Map<String, Map<String,String>> initClassifyMap(){
    	String hospName = mrqDictWeightApplication.getHospName();
    	List<Map<String, Object>> listMap = mrqDictWeightApplication.getAllMrqDictWeight(hospName);
    	Map<String, Map<String,String>> mapMap = new HashMap<String, Map<String,String>>();
    	if(null != listMap && listMap.size()>0){
    		for(Map<String, Object> map : listMap){
    			String className = (String)map.get("SCORE_CODE");
    			String classPart = (String)map.get("WEIGHT_CODE");
    			if(mapMap.containsKey(className)){
    				mapMap.get(className).put(classPart, classPart);
    			}else{
    				Map<String,String> mapString = new HashMap<String,String>();
    				mapString.put(classPart, classPart);
    				mapMap.put(className, mapString);
    			}
    		}		
    	}
    	return mapMap;
    }
    /**
     *  @Discription：定时任务调用转接，以QuartzJob结尾
     *  @Author： liuhongjun
     *  @param param
     *  @Date:2018年10月25日下午3:52:57
     */
    public void mrQualityQuartzJob(String param) {
        String now  = DrgsIndex.formateDateFrom(null) ;
        String dateFrom = MonitorResultUtil.addDay(now,-1) ;
        String dateTo  = dateFrom ;
        Map<String,Object> condition = new HashMap<>() ;
        condition.put("dateFrom",dateFrom) ;
        condition.put("dateTo",dateTo) ;
        condition.put("dateType","pushDate") ;
        condition.put("pageSize",2000) ;
        batchMedicalRecordQualityAnalysis(condition) ;
    
    }
}
